home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / drdobbs / 1987 / 11 / portlst.nov < prev    next >
Text File  |  1987-10-08  |  17KB  |  510 lines

  1.  
  2. Listing 1
  3.  
  4. /* VIDEO.I: Contains ROM BIOS video calls to be used in Turbo C */
  5.  
  6. #define  ROM  0x10
  7.  
  8. union REGS  inreg, outreg;
  9.  
  10. int videomode (int *ncols)             /* get current display mode */
  11. {                              /* return number of cols via *ncols */
  12.   inreg.h.ah = 0x0F;
  13.   int86 (ROM, &inreg, &outreg);
  14.   *ncols = outreg.h.ah;                          /* number of cols */
  15.   return (outreg.h.al);                             /* return mode */
  16. } /* ------------------------ */
  17. int activepage (void)                /* return active display page */
  18. {
  19.   inreg.h.ah = 0x0F;
  20.   int86 (ROM, &inreg, &outreg);
  21.   return (outreg.h.bh);
  22. } /* ------------------------ */
  23. void setmode (int mode)                          /* set video mode */
  24. {
  25.   inreg.h.al = mode;
  26.   inreg.h.ah = 0x00;
  27.   int86 (ROM, &inreg, &outreg);
  28. } /* ------------------------ */
  29. void setcursor (int start, int end)            /* set cursor shape */
  30. {
  31.   inreg.h.ch = start;
  32.   inreg.h.cl = end;
  33.   inreg.h.ah = 0x01;
  34.   int86 (ROM, &inreg, &outreg);
  35. } /* ------------------------ */
  36. int curstart (void)                    /* get cursor starting line */
  37. {
  38.   inreg.h.bh = 0;               /* (cursor shape same in all pages */
  39.   inreg.h.ah = 0x03;
  40.   int86 (ROM, &inreg, &outreg);
  41.   return (outreg.h.ch);
  42. } /* ------------------------ */
  43. int cursend (void)                       /* get cursor ending line */
  44. {
  45.   inreg.h.bh = 0;
  46.   inreg.h.ah = 0x03;
  47.   int86 (ROM, &inreg, &outreg);
  48.   return (outreg.h.cl);
  49. } /* ------------------------ */
  50. void cursoff (void)                             /* turn cursor off */
  51. {
  52.   inreg.h.ch = curstart () | 0x10;                /* turn on bit 4 */
  53.   inreg.h.cl = cursend ();
  54.   inreg.h.ah =  0x01;
  55.   int86 (ROM, &inreg, &outreg);
  56. } /* ------------------------ */
  57. void curson (void)                               /* turn cursor on */
  58. {
  59.   inreg.h.ch = curstart () & 0x07;     /* turn off high order bits */
  60.   inreg.h.cl = cursend ();
  61.   inreg.h.ah =  0x01;
  62.   int86 (ROM, &inreg, &outreg);
  63. } /* ------------------------ */
  64. void gotoxy (int col, int row, int page)         /* set cursor pos */
  65. {                                             /* must specify page */
  66.   inreg.h.bh = page;
  67.   inreg.h.dh = row;
  68.   inreg.h.dl = col;
  69.   inreg.h.ah = 0x02;
  70.   int86 (ROM, &inreg, &outreg);
  71. } /* ------------------------ */
  72. int wherex (int page)              /* return cursor column in page */
  73. {
  74.   inreg.h.bh = page;
  75.   inreg.h.ah = 0x03;
  76.   int86 (ROM, &inreg, &outreg);
  77.   return (outreg.h.dl);
  78. } /* ------------------------ */
  79. int wherey (int page)                 /* return cursor row in page */
  80. {
  81.   inreg.h.bh = page;
  82.   inreg.h.ah = 0x03;
  83.   int86 (ROM, &inreg, &outreg);
  84.   return (outreg.h.dh);
  85. } /* ------------------------ */
  86. void setpage (int page)                 /* set active display page */
  87. {
  88.   inreg.h.al = page;
  89.   inreg.h.ah = 0x05;
  90.   int86 (ROM, &inreg, &outreg);
  91. } /* ------------------------ */
  92. void cls (void)                             /* clear active screen */
  93. {
  94.   inreg.h.al = 25;                                /* entire screen */
  95.   inreg.h.bh = 0x07;                       /* set to gray on black */
  96.   inreg.h.ah = 0x06;
  97.   inreg.h.cl =  0; inreg.h.ch =  0;
  98.   inreg.h.dl = 79; inreg.h.dh = 24;
  99.   int86 (ROM, &inreg, &outreg);
  100.   gotoxy (0, 0, activepage ());
  101. } /* ------------------------ */
  102. void window (int  x1, int y1,          /* window upper left corner */
  103.              int  x2, int y2,                /* lower right corner */
  104.              char attrib)                 /* text attribute inside */
  105. {
  106.   inreg.h.al = y2 - y1 + 1;                 /* clear entire window */
  107.   inreg.h.bh = attrib;
  108.   inreg.h.cl = x1; inreg.h.ch = y1;
  109.   inreg.h.dl = x2; inreg.h.dh = y2;
  110.   inreg.h.ah = 0x06;
  111.   int86 (ROM, &inreg, &outreg);
  112. } /* ------------------------ */
  113. void winScroll (int x1, int y1, int x2, int y2,   /* scroll window */
  114.                 int attr)                       /* one line upward */
  115. {
  116.   inreg.h.al = 1;
  117.   inreg.h.cl = x1; inreg.h.ch = y1;
  118.   inreg.h.dl = x2; inreg.h.dh = y2;
  119.   inreg.h.bh = attr;
  120.   inreg.h.ah = 0x06;
  121.   int86 (ROM, &inreg, &outreg);
  122. } /* ------------------------ */
  123. char chattr (int foregrnd, int backgrnd)        /* character attrib*/
  124. {
  125.   return ((backgrnd << 4) + foregrnd);
  126. } /* ------------------------ */
  127. char rdchara (int page,                   /* read char at curs pos */
  128.               char *attrib)         /* return attribute indirectly */
  129. {
  130.   inreg.h.bh = page;
  131.   inreg.h.ah = 0x08;
  132.   int86 (ROM, &inreg, &outreg);
  133.   *attrib = outreg.h.ah;
  134.   return (outreg.h.al);
  135. } /* ------------------------ */
  136. void wrtcha (char ch, char attrib,          /* write char + attrib */
  137.              int page)                    /* at cursor pos on page */
  138. {                                 /* NOTE: does not advance cursor */
  139.   inreg.h.al = ch;
  140.   inreg.h.bh = page;
  141.   inreg.h.bl = attrib;
  142.   inreg.x.cx = 1;
  143.   inreg.h.ah = 0x09;
  144.   int86 (ROM, &inreg, &outreg);
  145. } /* ------------------------ */
  146. void wrtstra (char *str,                           /* write string */
  147.               char attrib,                       /* with attribute */
  148.               int page)                                 /* to page */
  149. {                                   /* starting at cursor position */
  150. int   c, r, n, p = 0;
  151.  
  152.   videomode (&n);                           /* get width of screen */
  153.   r = wherey (page);                            /* get current row */
  154.   while (str[p]) {
  155.     wrtcha (str[p++], attrib, page);            /* write next char */
  156.     if ((c = wherex (page)) < (n - 1))
  157.       gotoxy (c + 1, r, page);                   /* advance cursor */
  158.     else
  159.       gotoxy (0, ++r, page);                          /* else wrap */
  160.   }
  161. } /* ------------------------ */
  162. void wrtch (char ch, int color,            /* write char in color */
  163.             int page)               /* at cursor position on page */
  164. {
  165.   inreg.h.al = ch;
  166.   inreg.h.bl = color;
  167.   inreg.h.bh = page;
  168.   inreg.x.cx = 1;
  169.   inreg.h.ah = 0x0A;
  170.   int86 (ROM, &inreg, &outreg);
  171. } /* ------------------------ */
  172. void wrtstr  (char *str,                           /* write string */
  173.               char color,                              /* in color */
  174.               int page)                                 /* to page */
  175. {                                   /* starting at cursor position */
  176. int   c, r, n, p = 0;
  177.  
  178.   videomode (&n);                           /* get width of screen */
  179.   r = wherey (page);                            /* get current row */
  180.   while (str[p]) {
  181.     wrtcha (str[p++], color, page);             /* write next char */
  182.     if ((c = wherex (page)) < (n - 1))
  183.       gotoxy (c + 1, r, page);                   /* advance cursor */
  184.     else
  185.       gotoxy (0, ++r, page);                          /* else wrap */
  186.   }
  187. } /* ------------------------ */
  188. void palette (int palno)                      /* set color palette */
  189. {                                   /* valid only in mode 4 on CGA */
  190.   inreg.h.bh = 1;
  191.   inreg.h.bl = palno;
  192.   inreg.h.ah = 0x0B;
  193.   int86 (ROM, &inreg, &outreg);
  194. } /* ------------------------ */
  195. void graphbackground (int color)         /* set graphics b/g color */
  196. {
  197.   inreg.h.bh = 0;
  198.   inreg.h.bl = color;
  199.   inreg.h.ah = 0x0B;
  200.   int86 (ROM, &inreg, &outreg);
  201. } /* ------------------------ */
  202. void plot (int x, int y, int pixel)          /* plot pixel at x, y */
  203. {
  204.   inreg.h.al = pixel;                       /* pixel (color) value */
  205.   inreg.h.bh = 0;
  206.   inreg.x.cx = x;
  207.   inreg.x.dx = y;
  208.   inreg.h.ah = 0x0C;
  209.   int86 (ROM, &inreg, &outreg);
  210. } /* ------------------------ */
  211. int pixel (int x, int y)             /* return pixel value at x, y */
  212. {
  213.   inreg.x.cx = x;
  214.   inreg.x.dx = y;
  215.   inreg.h.ah = 0x0D;
  216.   int86 (ROM, &inreg, &outreg);
  217.   return (outreg.h.al);
  218. } /* ------------------------ */
  219.  
  220.  
  221.  
  222.  
  223. Listing 2
  224.  
  225. /* VIDEO.H: Prototypes for contents of user-written VIDEO.LIB */
  226. /* Describes calls to ROM BIOS video functions */
  227.  
  228. int videomode (int *ncols);
  229. int activepage (void);
  230. void setmode (int mode);
  231. void setcursor (int start, int end);
  232. int curstart (void);
  233. int cursend (void);
  234. void cursoff (void);
  235. void curson (void);
  236. void gotoxy (int col, int row, int page);
  237. int wherex (int page);
  238. int wherey (int page);
  239. void setpage (int page);
  240. void cls (void);
  241. void window (int x1, int y1, int x2, int y2, char attrib);
  242. char chattr (int fgrnd, int bgrnd);
  243. char rdchara (int page, char *attr);
  244. void wrtcha (char ch, char attr, int page);
  245. void wrtstra (char *str, char attr, int page);
  246. void wrtch (char ch, int color, int page);
  247. void wrtstr (char *str, char color, int page);
  248. void palette (int palno);
  249. void graphbackground (int color);
  250. void plot (int x, int y, int pixel);
  251. int pixel (int x, int y);
  252.  
  253.  
  254.  
  255.  
  256. Listing 3
  257.  
  258. /* DRAW.I: Draws lines in graphics mode */
  259.  
  260. /* hdraw draws horizontal line along y between x1 and x2 */
  261. void hdraw (int x1, int x2, int y, int color)
  262. {
  263. int   x;
  264.  
  265.   if (x1 > x2) {              /* sort x's into left-to-right order */
  266.     x = x1; x1 = x2; x2 = x;
  267.   }
  268.   for (x = x1; x <= x2; x++)
  269.     plot (x, y, color);
  270. } /* ------------------------ */
  271.  
  272. /* vdraw draws vertical line along x between y1 and y2 */
  273. void vdraw (int y1, int y2, int x, int color)
  274. {
  275. int    y;
  276.  
  277.   if (y1 > y2) {              /* sort y's into top-to-bottom order */
  278.     y = y1; y1 = y2; y2 = y;
  279.   }
  280.   for (y = y1; y <= y2; y++)
  281.     plot (x, y, color);
  282. } /* ------------------------ */
  283.  
  284. /* draw() does lines on the diagonal */
  285. void draw (int x1, int y1, int x2, int y2, int color)
  286. {
  287. double   xstep, ystep, xcum = 0.0, ycum = 0.0;
  288. int      dx, dy;                                         /* deltas */
  289. register x, y;
  290.  
  291.   dx = x2 - x1;
  292.   dy = y2 - y1;
  293.   if (abs (dx) >= abs (dy)) {                 /* plot along x axis */
  294.     ystep = (double) dy / dx;       /* movement along y axis per x */
  295.     if (dy < 0) {                         /* y travels to the left */
  296.       if (ystep > 0)
  297.         ystep *= -1;           /* adjust for wrong sign from -y/-x */
  298.     } else                               /* y travels to the right */
  299.       if (ystep < 0)
  300.         ystep *= -1;                            /* adjust as above */
  301.     dx /= abs (dx);                                 /* x increment */
  302.     for (x = x1, y = y1; x != x2; x += dx) {
  303.       plot (x, y, color);
  304.       ycum += ystep;                    /* cum motion along y axis */
  305.       y = y1 + ycum;                                     /* next y */
  306.     }
  307.   } else {                                    /* plot along y axis */
  308.     xstep = (double) dx / dy;       /* movement along x axis per y */
  309.     if (dx < 0) {
  310.       if (xstep > 0)
  311.         xstep *= -1;
  312.     } else
  313.       if (xstep < 0)
  314.         xstep *= -1;
  315.     dy /= abs (dy);                                 /* y increment */
  316.     for (y = y1, x = x1; y != y2; y += dy) {
  317.       plot (x, y, color);
  318.       xcum += xstep;                    /* cum motion along x axis */
  319.       x = x1 + xcum;                                     /* next x */
  320.     }
  321.   }
  322. } /* -------------------------- */
  323.  
  324.  
  325.  
  326.  
  327.  
  328. Listing 4
  329.  
  330. /* COLORS.H: Maps color names */
  331.  
  332. #define BLACK         0
  333. #define BLUE          1
  334. #define GREEN         2
  335. #define CYAN          3
  336. #define RED           4
  337. #define MAGENTA       5
  338. #define BROWN         6
  339. #define LIGHTGRAY     7
  340. #define DARKGRAY      8
  341. #define LIGHTBLUE     9
  342. #define LIGHTGREEN   10
  343. #define LIGHTCYAN    11
  344. #define LIGHTRED     12
  345. #define LIGHTMAGENTA 13
  346. #define YELLOW       14
  347. #define WHITE        15
  348.  
  349.  
  350.  
  351.  
  352.  
  353. Listing 5
  354.  
  355. /* VID.C: Demos video functions */
  356.  
  357. /* TURBO C INCLUDES */
  358. #include <stdio.h>
  359. #include <bios.h>
  360. #include <dos.h>
  361.  
  362. /* USER-WRITTEN INCLUDES */
  363. #include <colors.h>
  364. #include <video.i>
  365. #include <draw.i>
  366.  
  367. /* LOCAL FUNCTION PROTOTYPES */
  368. int  vidIdent (int *vidmode);
  369. void wait (void);
  370. void stairsteps (void);
  371. int  isEGA (void);
  372. void label (void);
  373. void bigX (int adap, int vmode);
  374. void hourglass (int adap, int vmode);
  375.  
  376. /* GLOBALS */
  377. enum vidTypes {mda, cga, ega, compaq, other};
  378.  
  379. main ()
  380. {
  381. int  adaptor, mode, cols;
  382.  
  383.   cls ();                                          /* clear screen */
  384.   adaptor = vidIdent (&mode);            /* identify video adaptor */
  385.   if (adaptor != other) {
  386.     stairsteps ();                      /* cursor positioning demo */
  387.     bigX (adaptor, mode);                      /* graphics demo #1 */
  388.     hourglass (adaptor, mode);                 /* graphics demo #2 */
  389.     label ();
  390.     gotoxy (36, 12, 0);
  391.     puts ("All done!");
  392.   }
  393. } /* ------------------------ */
  394. int  vidIdent (int *vidmode)             /* identify video adaptor */
  395. {
  396. int  flag, adap, width;
  397.  
  398.   label ();                                       /* label display */
  399.   puts ("\n\nDISPLAY INFORMATION:");
  400.   *vidmode = videomode (&width);                 /* get video mode */
  401.   flag = (biosequip () & 0x18) >> 4;        /* get video eqpt flag */
  402.   if (isEGA ()) {
  403.     adap = ega;
  404.     puts ("\n\n  Enhanced Graphics Adaptor");
  405.   } else
  406.     switch (flag) {
  407.       case 0: if (*vidmode == 2) {
  408.                 adap = compaq;
  409.                 puts ("\n\n  Compaq adaptor");
  410.               } else {
  411.                 adap = cga;
  412.                 puts ("\n\n  Color Graphics Adaptor");
  413.               }
  414.               break;
  415.       case 3: adap = mda;
  416.               puts ("\n\n  Monochrome Display Adaptor");
  417.               break;
  418.       default: adap = other;
  419.               puts ("\n\n  Adaptor not usable in this demo. Sorry.");
  420.     } /* end of switch */
  421.   printf ("\n  Text screen size is %d columns x 25 rows\n", width);
  422.   if ((*vidmode < 4) || (*vidmode == 7))
  423.     puts ("\n  Text mode currently active");
  424.   else
  425.     puts ("\n  Graphics mode currently active");
  426.   wait ();
  427.   return (adap);
  428. } /* ------------------------ */
  429. int  isEGA (void)                  /* determine if EGA is attached */
  430. {                               /* return TRUE if so, FALSE if not */
  431.   return (peekb (0x40, 0x87));              /* check EGA info byte */
  432. } /* ------------------------ */
  433. void wait (void)          /* prompt to continue, wait for keypress */
  434. {
  435. int   tab, width;
  436.  
  437.   videomode (&width);                      /* get width in columns */
  438.   tab = (width - 33) / 2;              /* starting column for text */
  439.   gotoxy (tab, 24, 0);
  440.   wrtstr ("Press any key to continue demo...", WHITE, 0);
  441.   getch ();
  442.   cls ();
  443. } /* ------------------------ */
  444. void label (void)                /* label the screen at top center */
  445. {
  446.   gotoxy (30, 0, 0);
  447.   wrtstra ("Video demonstration", chattr (YELLOW, BLUE), 0);
  448. } /* ------------------------ */
  449. void stairsteps (void)
  450. {
  451. int   color = 1;
  452.  
  453.    label ();
  454.    gotoxy (31,  2, 0); wrtstr ("Cursor positioning", LIGHTGRAY, 0);
  455.    gotoxy (10,  4, 0); wrtstr ("Stair", color++, 0);
  456.    gotoxy (20, 10, 0); wrtstr ("steps", color++, 0);
  457.    gotoxy (30, 16, 0); wrtstr ("going", color++, 0);
  458.    gotoxy (40, 22, 0); wrtstr ("down",  color++, 0);
  459.    gotoxy (50, 16, 0); wrtstr ("and",   color++, 0);
  460.    gotoxy (60, 10, 0); wrtstr ("back",  color++, 0);
  461.    gotoxy (70,  4, 0); wrtstr ("up",    color, 0);
  462.    wait ();
  463. } /* ------------------------ */
  464. void bigX (int vidAdap, int vmode)         /* APA graphics demo #1 */
  465. {                     /* draws full-screen border and X, adjusting */
  466.                                     /* for EGA or CGA as indicated */
  467. int  x1 =  0, x2 = 639;
  468. int  y1 = 15, y2;
  469.  
  470.   if ((vidAdap == mda) || (vidAdap == other))       /* can't do it */
  471.     return;                            /* so return with no action */
  472.  
  473.   if (vidAdap == ega) {          /* EGA demo: 640 x 350 (mode 0Fh) */
  474.     y2 = 349 - 15;                /* set bottom of graphics screen */
  475.     setmode (0x0F);                /* go to EGA mono graphics mode */
  476.   } else {                /* CGA|Compaq demo: 640 x 200 (mode 06h) */
  477.     y2 = 199 - 15;
  478.     setmode (0x06);
  479.   }
  480.   label ();                                    /* label the screen */
  481.   hdraw (x1, x2, y1, 1);                   /* draw line across top */
  482.   hdraw (x1, x2, y2, 1);                            /* then bottom */
  483.   vdraw (y1, y2, x1, 1);                         /* down left side */
  484.   vdraw (y1, y2, x2, 1);                        /* down right side */
  485.   draw (x1, y1, x2, y2, 1);                       /* main diagonal */
  486.   draw (x1, y2, x2, y1, 1);                      /* cross diagonal */
  487.   wait ();
  488.   setmode (vmode);
  489. } /* ------------------------ */
  490. void hourglass (int vidAdap, int vmode)        /* graphics demo #2 */
  491. {                   /* operates in 320 x 200 four-color (CGA) mode */
  492. int     y, x1 = 60, x2 = 260, pixval = 1;
  493.  
  494.   if ((vidAdap == mda) || (vidAdap == other))       /* can't do it */
  495.     return;                                          /* so go back */
  496.   setmode (4);                          /* go to CGA graphics mode */
  497.   gotoxy (8, 0, 0);
  498.   puts ("320 x 200 color graphics");                  /* show mode */
  499.   palette (0);
  500.   for (y = 50; y < 151; y++ ) {                     /* draw figure */
  501.     hdraw (x1, x2, y, pixval);
  502.     x1 += 2; x2 -= 2;                                /* change x's */
  503.     if (y ==  84) pixval = 2;                     /* change colors */
  504.     if (y == 117) pixval = 3;
  505.   }
  506.   wait ();
  507.   setmode (vmode);
  508. } /* ------------------------ */
  509.  
  510.